using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using Microsoft.Feeds.Interop;
using System.IO;

namespace RSStoZPL
{
    class CustomContext : ApplicationContext
    {
        private IContainer components;
        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.NotifyIcon notifyIcon1;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
        private System.Windows.Forms.ToolStripMenuItem runNowMenuItem;
        private System.Windows.Forms.ToolStripMenuItem setPlaylistLocationMenuItem;
        private System.Windows.Forms.ToolStripMenuItem setEnclosureLocationMenuItem;
        private System.Windows.Forms.ToolStripMenuItem closeMenuItem;
        private System.Windows.Forms.ToolStripMenuItem setDownloadIntervalMenuItem;
        private System.Windows.Forms.ToolStripMenuItem setAutoDeleteMenuItem;

        public CustomContext()
        {
            InitializeContext();
            if (CanStartProcessing)
            {
                RunAndStartTimer();
            }
            else
            {
                notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                notifyIcon1.ShowBalloonTip(5000, "Hey!", "I don't know where to put or files and/or your playlists. Open my menus and set these and I'll start running.", ToolTipIcon.Warning);
            }
            setAutoDeleteMenuItem.Checked = Properties.Settings.Default.CleanUpFeeds;
        }

        private void RunAndStartTimer()
        {
            StartFeedScan();
            timer1.Interval = RSStoZPL.Properties.Settings.Default.RunInterval;
            timer1.Start();
        }

        private void StartFeedScan()
        {
            backgroundWorker1.RunWorkerAsync();
            notifyIcon1.ShowBalloonTip(5000, "Processing...", "Starting to process your feeds now", ToolTipIcon.Info);
        }

        private bool CanStartProcessing
        {
            get
            {
                return !string.IsNullOrEmpty(RSStoZPL.Properties.Settings.Default.FeedFileLocation) && !string.IsNullOrEmpty(RSStoZPL.Properties.Settings.Default.PlayListLocation);
            }
        }

        private void InitializeContext()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.closeMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.setPlaylistLocationMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.setEnclosureLocationMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.runNowMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.setDownloadIntervalMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.setAutoDeleteMenuItem = new ToolStripMenuItem();
            this.contextMenuStrip1.SuspendLayout();
            // 
            // timer1
            // 
            this.timer1.Interval = RSStoZPL.Properties.Settings.Default.RunInterval;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // notifyIcon1
            // 
            this.notifyIcon1.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            this.notifyIcon1.BalloonTipText = "Processing your feeds now...";
            this.notifyIcon1.BalloonTipTitle = "Processing";
            this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
            this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
            this.notifyIcon1.Text = "RSStoZPL";
            this.notifyIcon1.Visible = true;
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
            this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
            // 
            // contextMenuStrip1
            // 
            this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.setAutoDeleteMenuItem,
            this.runNowMenuItem,
            this.setPlaylistLocationMenuItem,
            this.setEnclosureLocationMenuItem,
            this.setDownloadIntervalMenuItem,
            this.closeMenuItem});
            this.contextMenuStrip1.Name = "contextMenuStrip1";
            this.contextMenuStrip1.Size = new System.Drawing.Size(203, 114);
            // 
            // closeMenuItem
            // 
            this.closeMenuItem.Name = "closeMenuItem";
            this.closeMenuItem.Size = new System.Drawing.Size(202, 22);
            this.closeMenuItem.Text = "Close";
            this.closeMenuItem.Click += new System.EventHandler(this.closeMenuItem_Click);
            // 
            // setPlaylistLocationMenuItem
            // 
            this.setPlaylistLocationMenuItem.Name = "setPlaylistLocationMenuItem";
            this.setPlaylistLocationMenuItem.Size = new System.Drawing.Size(202, 22);
            this.setPlaylistLocationMenuItem.Text = "Set Playlist Location...";
            this.setPlaylistLocationMenuItem.Click += new System.EventHandler(this.setPlaylistLocationMenuItem_Click);
            // 
            // setEnclosureLocationMenuItem
            // 
            this.setEnclosureLocationMenuItem.Name = "setEnclosureLocationMenuItem";
            this.setEnclosureLocationMenuItem.Size = new System.Drawing.Size(202, 22);
            this.setEnclosureLocationMenuItem.Text = "Set Enclosure Location...";
            this.setEnclosureLocationMenuItem.Click += new System.EventHandler(this.setEnclosureLocationMenuItem_Click);
            // 
            // runNowMenuItem
            // 
            this.runNowMenuItem.DoubleClickEnabled = true;
            this.runNowMenuItem.Name = "runNowMenuItem";
            this.runNowMenuItem.Size = new System.Drawing.Size(202, 22);
            this.runNowMenuItem.Text = "Run Now";
            this.runNowMenuItem.Click += new System.EventHandler(this.runNowMenuItem_Click);
            // 
            // setDownloadIntervalMenuItem
            // 
            this.setDownloadIntervalMenuItem.DoubleClickEnabled = true;
            this.setDownloadIntervalMenuItem.Name = "setDownloadIntervalMenuItem";
            this.setDownloadIntervalMenuItem.Size = new System.Drawing.Size(202, 22);
            this.setDownloadIntervalMenuItem.Text = "Set Update Interval...";
            this.setDownloadIntervalMenuItem.Click += new EventHandler(setDownloadInterval_Click);
            //
            // setAutoDeleteMenuItem
            //
            this.setAutoDeleteMenuItem.CheckOnClick = true;
            this.setAutoDeleteMenuItem.Name = "setAutoDeleteMenuItem";
            this.setAutoDeleteMenuItem.Size = new System.Drawing.Size(202, 22);
            this.setAutoDeleteMenuItem.Text = "Auto prune files";
            this.setAutoDeleteMenuItem.CheckStateChanged += new EventHandler(setAutoDeleteMenuItem_CheckStateChanged);

            this.contextMenuStrip1.ResumeLayout(false);
        }

        void setAutoDeleteMenuItem_CheckStateChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.CleanUpFeeds = setAutoDeleteMenuItem.Checked;
        }

        void setDownloadInterval_Click(object sender, EventArgs e)
        {
            int newValue = IntervalSet.Prompt();
            if (newValue > 0)
            {
                RSStoZPL.Properties.Settings.Default.RunInterval = newValue;
                timer1.Interval = RSStoZPL.Properties.Settings.Default.RunInterval;
                RSStoZPL.Properties.Settings.Default.Save();
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
        }	

        private void ProcessFolder(IFeedFolder folder)
        {
            foreach (IFeedFolder subfolder in folder.Subfolders as IFeedsEnum)
            {
                ProcessFolder(subfolder);
            }
            foreach (IFeed feed in folder.Feeds as IFeedsEnum)
            {
                ProcessFeed(feed);
            }
        }

        private void ProcessFeed(IFeed feed)
        {
            if (feed.DownloadEnclosuresAutomatically)
            {
                ZunePlaylist feedPlaylist = new ZunePlaylist();
                feedPlaylist.Title = feed.Title;
                string feedDir = Path.Combine(RSStoZPL.Properties.Settings.Default.FeedFileLocation, ZunePlaylist.CleanupFilename(feed.Title));
                if (!Directory.Exists(feedDir))
                {
                    Directory.CreateDirectory(feedDir);
                }
                foreach (IFeedItem feedItem in feed.Items as IFeedsEnum)
                {
                    ProcessFeedItem(feedPlaylist, feedItem, feedDir);
                }
                if (RSStoZPL.Properties.Settings.Default.CleanUpFeeds)
                {
                    List<string> filesOnDisk = new List<string>(Directory.GetFiles(feedDir));
                    foreach (string fileOnDisk in filesOnDisk)
                    {
                        if (feedPlaylist.Items.Find(
                            delegate(ZunePlaylist.ZunePlaylistItem item)
                            {
                                if (item.MediaFile == fileOnDisk)
                                    return true;
                                return false;
                            }) == null)
                        {
                            File.Delete(fileOnDisk);
                        }
                    }
                }
                if (feedPlaylist.Items.Count > 0)
                {
                    string goodFileName = ZunePlaylist.CleanupFilename(feedPlaylist.Title);
                    feedPlaylist.Save(Path.ChangeExtension(Path.Combine(RSStoZPL.Properties.Settings.Default.PlayListLocation, goodFileName), ".zpl"));
                    backgroundWorker1.ReportProgress(50, string.Format("Created {0} with {1} items", feedPlaylist.Title, feedPlaylist.Items.Count));
                }
            }
        }

        private void ProcessFeedItem(ZunePlaylist feedPlaylist, IFeedItem feedItem, string feedDir)
        {
            if (feedItem.Enclosure != null)
            {
                IFeedEnclosure enclosure = feedItem.Enclosure as IFeedEnclosure;
                if (enclosure.DownloadStatus == FEEDS_DOWNLOAD_STATUS.FDS_DOWNLOADED)
                {
                    string newLocalLocation = Path.Combine(feedDir, Path.GetFileName(enclosure.LocalPath));
                    if (!File.Exists(newLocalLocation) && File.Exists(enclosure.LocalPath))
                        File.Move(enclosure.LocalPath, newLocalLocation);
                    feedPlaylist.Items.Add(new ZunePlaylist.ZunePlaylistItem(newLocalLocation));
                }
            }
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            StartFeedScan();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            FeedsManager feedManager = new FeedsManagerClass();
            IFeedFolder root = feedManager.RootFolder as IFeedFolder;
            ProcessFolder(root);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            notifyIcon1.ShowBalloonTip(5000, "Feed complete", e.UserState as string, ToolTipIcon.Info);
        }

        private void runNowMenuItem_Click(object sender, EventArgs e)
        {
            StartFeedScan();
        }

        private void closeMenuItem_Click(object sender, EventArgs e)
        {
            notifyIcon1.Visible = false;
            Application.Exit();
        }

        private void setPlaylistLocationMenuItem_Click(object sender, EventArgs e)
        {
            string newPath = GetFolderPath(RSStoZPL.Properties.Settings.Default.PlayListLocation);
            if (!string.IsNullOrEmpty(newPath))
            {
                RSStoZPL.Properties.Settings.Default.PlayListLocation = newPath;
                RSStoZPL.Properties.Settings.Default.Save();
            }
            if (!timer1.Enabled && CanStartProcessing)
            {
                RunAndStartTimer();
            }
        }

        private void setEnclosureLocationMenuItem_Click(object sender, EventArgs e)
        {
            string newPath = GetFolderPath(RSStoZPL.Properties.Settings.Default.FeedFileLocation);
            if (!string.IsNullOrEmpty(newPath))
            {
                RSStoZPL.Properties.Settings.Default.FeedFileLocation = newPath;
                RSStoZPL.Properties.Settings.Default.Save();
            }
            if (!timer1.Enabled && CanStartProcessing)
            {
                RunAndStartTimer();
            }
        }

        private string GetFolderPath(string defaultPath)
        {
            FolderBrowserDialog diag = new FolderBrowserDialog();
            diag.SelectedPath = defaultPath;
            if (diag.ShowDialog() == DialogResult.OK)
                return diag.SelectedPath;
            else
                return null;
        }

        protected override void ExitThreadCore()
        {
            timer1.Enabled = false;
            base.ExitThreadCore();
        }
    }
}
